
package com.boarsoft.boar.soagov.svc.action;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.boarsoft.bean.ReplyInfo;
import com.boarsoft.boar.common.Constants;
import com.boarsoft.common.Util;
import com.boarsoft.common.util.JsonUtil;
import com.boarsoft.rpc.core.RpcContext;
import com.boarsoft.soagov.spy.SpyData;
import com.boarsoft.soagov.spy.SvcSpy;
import com.boarsoft.soagov.spy.TpsBucket;

@RestController
@RequestMapping("/svc/monitor")
public class SvcMonitorAction {
	private static final Logger log = LoggerFactory.getLogger(SvcMonitorAction.class);

	@Autowired
	private SvcSpy svcSpy;

	@SuppressWarnings("unchecked")
	@RequestMapping("/tps.do")
	// @Authorized(code = "svc.inst.tps")
	public ReplyInfo<Object> tps(String key, String addr) {
		if (Util.strIsEmpty(key)) {
			return new ReplyInfo<Object>(Constants.WARN_INVALID, "服务码");
		}
		Map<String, Integer> xm = new HashMap<String, Integer>();
		// 如果没有提交监控地址，则取平均监控结果
		if (Util.strIsEmpty(addr)) {
			// 广播监控所有该服务的提供者
			Map<String, Object> rm = (Map<String, Object>) svcSpy.getData(key);
			if (rm == null || rm.isEmpty()) {
				return new ReplyInfo<Object>(Constants.ERROR_NOTFOUND);
			}
			xm.put("global", 0);
			for (Entry<String, Object> en : rm.entrySet()) {
				String a = en.getKey();
				Object o = en.getValue();
				if (o != null && o instanceof SpyData) {
					SpyData d = (SpyData) o;
					TpsBucket b = d.getTpsBucket();
					xm.put("global", xm.get("global") + b.getLastTps());
					//
					Map<String, TpsBucket> bm = d.getTpsBucketMap();
					for (String k : bm.keySet()) {
						TpsBucket t = bm.get(k);
						if (xm.containsKey(k)) {
							xm.put(k, xm.get(k) + t.getLastTps());
						} else {
							xm.put(k, t.getLastTps());
						}
					}
				} else {
					log.warn("Remote node {} return {}", a, o);
				}
			}
		} else {
			SpyData d = null;
			RpcContext.specify2(addr);
			try {
				d = svcSpy.getSpyData(key);
			} finally {
				RpcContext.specify2(null);
			}
			if (d != null) {
				xm.put("global", d.getTpsBucket().getLastTps());
				//
				Map<String, TpsBucket> bm = d.getTpsBucketMap();
				for (String k : bm.keySet()) {
					xm.put(k, bm.get(k).getLastTps());
				}
			}
		}
		log.info("{}@{}={}", key, addr, JsonUtil.from(xm));
		return new ReplyInfo<Object>(true, xm);
	}
}